home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2 Examples.sit / Raven 1.2 Examples / Quill / Source / ResourceSubNode.cpp < prev    next >
C/C++ Source or Header  |  1997-01-27  |  9KB  |  361 lines

  1. /*
  2.  *  File:       ResourceSubNode.cpp
  3.  *  Summary:       A node containing CResourceTable nodes.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1997 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):    
  10.  *
  11.  *         <->     1/17/96    JDJ        Created
  12.  */
  13.  
  14. #include "ResourceSubNode.h"
  15.  
  16. #include <CType.h>
  17.  
  18. #include <ZDialogUtils.h>
  19. #include <ZHierarchicalTableExtras.h>
  20. #include <ZStream.h>
  21.  
  22.  
  23. // ===================================================================================
  24. //    Internal Functions
  25. // ===================================================================================
  26.  
  27. //---------------------------------------------------------------
  28. //
  29. // DuplicateResourceFilter
  30. //
  31. //---------------------------------------------------------------
  32. static pascal Boolean DuplicateResourceFilter(DialogPtr dptr, EventRecord* event, short* item)
  33. {
  34.     Boolean handled = DefaultFilter(dptr, event, item);
  35.     
  36.     if (!handled && event->what == keyDown) {
  37.         char ch = toupper(event->message & charCodeMask);
  38.         if (ch == 'R') { 
  39.             *item = 1;
  40.             handled = true;
  41.         } else if (ch == 'U') { 
  42.             *item = 3;
  43.             handled = true;
  44.         }
  45.         if (handled) 
  46.             FlashButton(dptr, *item);
  47.     }
  48.     
  49.     return handled;
  50. }
  51.  
  52. #pragma mark -
  53.  
  54. // ===================================================================================
  55. //    class CResourceSubNode
  56. // ===================================================================================
  57.  
  58. //---------------------------------------------------------------
  59. //
  60. // CResourceSubNode::~CResourceSubNode
  61. //
  62. //---------------------------------------------------------------
  63. CResourceSubNode::~CResourceSubNode()
  64. {
  65.     delete mExemplar;
  66. }
  67.  
  68.  
  69. //---------------------------------------------------------------
  70. //
  71. // CResourceSubNode::CResourceSubNode
  72. //
  73. //---------------------------------------------------------------
  74. CResourceSubNode::CResourceSubNode(THierarchicalTable* table, TSubNode* parent, const string& title, CResourceNode* exemplar) : TSubNode(table, parent, title, true)
  75. {
  76.     ASSERT(exemplar != nil);
  77.     
  78.     mExemplar = exemplar;
  79.  
  80.     mExemplar->GetMap()->AddListener(this);
  81. }
  82.  
  83.  
  84. //---------------------------------------------------------------
  85. //
  86. // CResourceSubNode::FindID
  87. //
  88. //---------------------------------------------------------------
  89. long CResourceSubNode::FindID(ResID id) const
  90. {
  91.     long at = -1;
  92.     
  93.     long count = this->GetNumNodes();
  94.     for (long index = 0; index < count && at < 0; index++) {
  95.         const CResourceNode* subNode = dynamic_cast<const CResourceNode*>(this->GetNode(index));
  96.         
  97.         if (id == subNode->GetID())
  98.             at = index;
  99.     }
  100.     
  101.     ASSERT(at >= 0);
  102.     
  103.     return at;
  104. }
  105.  
  106.  
  107. //---------------------------------------------------------------
  108. //
  109. // CResourceSubNode::HasSelection
  110. //
  111. //---------------------------------------------------------------
  112. bool CResourceSubNode::HasSelection() const
  113. {
  114.     bool has = false;
  115.     
  116.     long count = this->GetNumNodes();
  117.     for (long index = 0; index < count && !has; index++) {
  118.         const TBaseTableNode* node = this->GetNode(index);
  119.         
  120.         has = node->IsSelected();
  121.     }
  122.     
  123.     return has;
  124. }
  125.  
  126. #pragma mark ハ
  127.  
  128. //---------------------------------------------------------------
  129. //
  130. // CResourceSubNode::DoCopy
  131. //
  132. //---------------------------------------------------------------
  133. void CResourceSubNode::DoCopy(TOutStream& stream)
  134. {    
  135.     ASSERT(this->HasSelection());
  136.     
  137.     THierarchicalIter<CResourceNode> iter(this);
  138.     while (iter) {
  139.         CResourceNode* node = *iter;
  140.         ++iter;
  141.         
  142.         if (node->IsSelected()) {
  143.             node->UpdateResource();
  144.         
  145.             const SResource& rsrc = node->GetResource();
  146.         
  147.             stream << rsrc;
  148.         }
  149.     }
  150. }
  151.  
  152.  
  153. //---------------------------------------------------------------
  154. //
  155. // CResourceSubNode::DoPaste
  156. //
  157. //---------------------------------------------------------------
  158. void CResourceSubNode::DoPaste(TInStream& stream)
  159. {    
  160.     while (!stream.AtEnd()) {
  161.         SResource rsrc;
  162.         stream >> rsrc;
  163.         
  164.         this->DoAddResource(rsrc);
  165.     }
  166. }
  167.  
  168.  
  169. //---------------------------------------------------------------
  170. //
  171. // CResourceSubNode::DoClear
  172. //
  173. //---------------------------------------------------------------
  174. void CResourceSubNode::DoClear()
  175. {
  176.     long count = this->GetNumNodes();
  177.     for (long index = count-1; index >= 0; index--) {        // start from rear since we're changing the collection
  178.         CResourceNode* node = dynamic_cast<CResourceNode*>(this->GetNode(index));
  179.         
  180.         if (node->IsSelected())
  181.             mExemplar->GetMap()->DeleteResource(node->GetID());
  182.     }
  183. }
  184.  
  185.  
  186. //---------------------------------------------------------------
  187. //
  188. // CResourceSubNode::DoSaveState
  189. //
  190. //---------------------------------------------------------------
  191. void CResourceSubNode::DoSaveState(TOutStream& stream) const
  192. {
  193.     long count = this->GetNumNodes();
  194.     stream << count;
  195.     
  196.     for (long index = 0; index < count; index++) {
  197.         const CResourceNode* node = dynamic_cast<const CResourceNode*>(this->GetNode(index));
  198.  
  199.         node->UpdateResource();
  200.         
  201.         const SResource& rsrc = node->GetResource();
  202.  
  203.         stream << rsrc << node->IsSelected() << mExemplar->GetMap()->IsDirty(rsrc.id);
  204.     }
  205. }
  206.  
  207.  
  208. //---------------------------------------------------------------
  209. //
  210. // CResourceSubNode::DoRestoreState
  211. //
  212. //---------------------------------------------------------------
  213. void CResourceSubNode::DoRestoreState(TInStream& stream)
  214. {
  215.     // Out with the old
  216.     while (this->GetNumNodes() > 0) {
  217.         CResourceNode* node = dynamic_cast<CResourceNode*>(this->GetNode(0));
  218.         
  219.         mExemplar->GetMap()->DeleteResource(node->GetID());
  220.     }
  221.     
  222.     // and in with the new.
  223.     long count;
  224.     stream >> count;
  225.     
  226.     for (long index = 0; index < count; index++) {
  227.         SResource rsrc;
  228.         stream >> rsrc;
  229.     
  230.         mExemplar->GetMap()->AddResource(rsrc);
  231.         
  232.         bool selected, dirty;
  233.         stream >> selected >> dirty;
  234.         
  235.         if (!dirty)
  236.             mExemplar->GetMap()->ClearDirty(rsrc.id);
  237.  
  238.         if (selected) {
  239.             long index = this->FindID(rsrc.id);
  240.             CResourceNode* node = dynamic_cast<CResourceNode*>(this->GetNode(index));
  241.             node->Select();
  242.         }
  243.     }
  244. }
  245.  
  246.  
  247. //---------------------------------------------------------------
  248. //
  249. // CResourceSubNode::DoAddResource
  250. //
  251. //---------------------------------------------------------------
  252. bool CResourceSubNode::DoAddResource(const SResource& inRsrc)
  253. {
  254.     bool add = true;
  255.     
  256.     SResource rsrc = inRsrc;
  257.     
  258.     if (rsrc.id == kIndeterminateID)
  259.         rsrc.id = mExemplar->GetMap()->GetLastResourceID() + 1;
  260.  
  261.     if (mExemplar->GetMap()->HasResource(rsrc.id)) {
  262.         short item = ::DoAlert(257, DuplicateResourceFilter);
  263.         if (item == ok) {
  264.             mExemplar->GetMap()->DeleteResource(rsrc.id);
  265.             
  266.         } else if (item == cancel)
  267.             add = false;
  268.             
  269.         else 
  270.             rsrc.id = mExemplar->GetMap()->GetLastResourceID() + 1;
  271.     }
  272.  
  273.     if (add) {
  274.         mExemplar->GetMap()->AddResource(rsrc);
  275.  
  276.         long index = this->FindID(rsrc.id);
  277.         CResourceNode* node = dynamic_cast<CResourceNode*>(this->GetNode(index));
  278.         node->Select();
  279.     }
  280.     
  281.     return add;
  282. }
  283.  
  284.  
  285. //---------------------------------------------------------------
  286. //
  287. // CResourceSubNode::OnBroadcast
  288. //
  289. //---------------------------------------------------------------
  290. void CResourceSubNode::OnBroadcast(const SResourceMapMessage& mesg)
  291. {
  292.     ASSERT(mesg.rsrcMap == mExemplar->GetMap());
  293.     
  294.     long index = 0;
  295.     CResourceNode* node = nil;
  296.  
  297.     switch (mesg.message) {
  298.         case kDeletingResources:
  299.             while (this->GetNumNodes() > 0)
  300.                 this->DeleteNode(0);
  301.             break;
  302.             
  303.         case kAddedResource:
  304.             node = mExemplar->Make(this, mesg.newRsrc.id);
  305.             this->AddNode(node);
  306.             break;
  307.             
  308.         case kDeletedResource:
  309.             index = this->FindID(mesg.oldRsrc.id);
  310.             this->DeleteNode(index);
  311.             break;
  312.             
  313.         case kSetResourceName:
  314.         case kSetResourceData:
  315.         case kSavedResource:
  316.             index = this->FindID(mesg.oldRsrc.id);
  317.             node = dynamic_cast<CResourceNode*>(this->GetNode(index));
  318.             
  319.             node->Invalidate();
  320.             break;
  321.             
  322.         case kSetResourceID:
  323.             index = this->FindID(mesg.oldRsrc.id);
  324.             node = dynamic_cast<CResourceNode*>(this->GetNode(index));
  325.             node->SetID(mesg.newRsrc.id);
  326.             
  327.             this->RemoveNode(index);
  328.             this->AddNode(node);
  329.             break;
  330.     }
  331. }
  332.  
  333. #pragma mark ハ
  334.  
  335. //---------------------------------------------------------------
  336. //
  337. // CResourceSubNode::AddNode
  338. //
  339. //---------------------------------------------------------------
  340. void CResourceSubNode::AddNode(CResourceNode* node)
  341. {
  342.     ASSERT(node != nil);
  343.         
  344.     long count = this->GetNumNodes();
  345.     long at = -1;
  346.  
  347.     for (long index = 0; index < count && at < 0; index++) {
  348.         CResourceNode* subNode = dynamic_cast<CResourceNode*>(this->GetNode(index));
  349.         
  350.         if (subNode->GetID() > node->GetID())
  351.             at = index;
  352.     }
  353.     
  354.     if (at == -1)
  355.         at = count;
  356.     
  357.     this->InsertNode(at, node);
  358. }
  359.  
  360.  
  361.